home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / langs / iconv8_s.arc / ICONT.ARC / TMAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-28  |  13.0 KB  |  528 lines

  1. /*
  2.  * tmain.c - main program for translator and linker.
  3.  */
  4.  
  5. #include "..\h\config.h"
  6. #include "general.h"
  7. #include "tproto.h"
  8. #include "..\h\paths.h"
  9.  
  10. /*
  11.  * Prototypes.
  12.  */
  13.  
  14. hidden    novalue    execute    Params((char *ofile,char *efile,char * *args));
  15. hidden    novalue    report Params((char *s));
  16. hidden    novalue    rmfiles Params((char **p));
  17. hidden    novalue    usage Params((noargs));
  18.  
  19. /*
  20.  * The following code is operating-system dependent [@tmain.01].  Include
  21.  *  files and such.
  22.  */
  23.  
  24. #if PORT
  25. Deliberate syntax error
  26. #endif                    /* PORT */
  27.  
  28. #if AMIGA || HIGHC_386 || MSDOS || MVS || UNIX || VM || VMS
  29. /* nothing is needed */
  30. #endif                    /* AMIGA || HIGHC_386 || ... */
  31.  
  32. #if ATARI_ST
  33. char *patharg;
  34. #endif                    /* ATARI_ST */
  35.  
  36. #if MACINTOSH
  37. #if MPW
  38. #include <fcntl.h>    \* MPW3 - for unlink() *\
  39. #include <CursorCtl.h>
  40. void SortOptions();
  41. #endif                    /* MPW */
  42. #endif                    /* MACINTOSH */
  43.  
  44. #if OS2
  45. #include <process.h>
  46. #endif                    /* OS2 */
  47. /*
  48.  * End of operating-system specific code.
  49.  */
  50.  
  51. #if IntBits == 16
  52. #ifdef strlen
  53. #undef strlen                /* pre-defined in some contexts */
  54. #endif                    /* strlen */
  55. #endif                    /* Intbits == 16 */
  56.  
  57. #ifndef Iconx
  58. #define Iconx IconxPath
  59. #endif                    /* Iconx */
  60.  
  61. /*
  62.  *  Define global variables.
  63.  */
  64.  
  65. #define Global
  66. #define Init(v) = v
  67. #include "globals.h"
  68.  
  69. char *ofile = NULL;            /* linker output file name */
  70.  
  71. /*
  72.  * getopt() variables
  73.  */
  74. extern int optind;        /* index into parent argv vector */
  75. extern int optopt;        /* character checked for validity */
  76. extern char *optarg;        /* argument associated with option */
  77.  
  78. /*
  79.  *  main program
  80.  */
  81. novalue main(argc,argv)
  82. int argc;
  83. char **argv;
  84.    {
  85.    int nolink = 0;            /* suppress linking? */
  86.    int errors = 0;            /* translator and linker errors */
  87.    char **tfiles, **tptr;        /* list of files to translate */
  88.    char **lfiles, **lptr;        /* list of files to link */
  89.    char **rfiles, **rptr;        /* list of files to remove */
  90.    char *efile = NULL;            /* stderr file */
  91.    char buf[MaxFileName];        /* file name construction buffer */
  92.    int c, n;
  93.    struct fileparts *fp;
  94.  
  95. #if MACINTOSH
  96. #if MPW
  97.    InitCursorCtl(NULL);
  98.    SortOptions(argv);
  99. #endif                    /* MPW */
  100. #endif                    /* MACINTOSH */
  101.  
  102.    /*
  103.     * Process options.
  104.     */
  105.    while ((c = getopt(argc,argv,Options)) != EOF)
  106.       switch (c) {
  107.          case 'c':            /* -c: compile only (no linking) */
  108.             nolink = 1;
  109.             break;
  110.          case 'e':            /* -e file: redirect stderr */
  111.             efile = optarg;
  112.             break;
  113.          case 'm':            /* -m: preprocess using m4(1) [UNIX] */
  114.             m4pre = 1;
  115.             break;
  116.          case 'o':            /* -o file: name output file */
  117.             ofile = optarg;
  118.             break;
  119.  
  120. #if ATARI_ST
  121.          case 'p':            /* -p path: iconx path [ATARI] */
  122.             patharg = optarg;
  123.             break;
  124. #endif                    /* ATARI_ST */
  125.  
  126.          case 's':            /* -s: suppress informative messages */
  127.             silent = 1;
  128.             break;
  129.          case 'u':            /* -u: warn about undeclared ids */
  130.             uwarn = 1;
  131.             break;
  132.          case 't':            /* -t: turn on procedure tracing */
  133.             trace = -1;
  134.             break;
  135.  
  136.  
  137.          case 'L':            /* -L: enable linker debugging */
  138.  
  139. #ifdef DeBugLinker
  140.             Dflag = 1;
  141. #endif                    /* DeBugLinker */
  142.  
  143.             break;
  144.  
  145.          case 'S':            /* -Sxnnnn: set a size */
  146.             sizearg(optarg,argv);
  147.             break;
  148.          default:
  149.          case 'x':            /* -x illegal until after file list */
  150.             usage();
  151.          }
  152.  
  153.    /*
  154.     * Allocate space for lists of file names.
  155.     */
  156.    n = argc - optind + 1;
  157.    tptr = tfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  158.    lptr = lfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  159.    rptr = rfiles = (char **)alloc((unsigned int)(2 * n * sizeof(char *)));
  160.  
  161.    /*
  162.     * Scan file name arguments.
  163.     */
  164.    while (optind < argc)  {
  165.       if (strcmp(argv[optind],"-x") == 0)    /* stop at -x */
  166.          break;
  167.       else if (strcmp(argv[optind],"-") == 0) {
  168.          *tptr++ = "-";                /* "-" means standard input */
  169.          *lptr++ = *rptr++ = "stdin.u1";
  170.          *rptr++ = "stdin.u2";
  171.          }
  172.       else {
  173.          fp = fparse(argv[optind]);        /* parse file name */
  174.          if (*fp->ext == '\0' || smatch(fp->ext, SourceSuffix)) {
  175.             makename(buf,SourceDir,argv[optind], SourceSuffix);
  176.             *tptr++ = salloc(buf);        /* translate the .icn file */
  177.             makename(buf,TargetDir,argv[optind],U1Suffix);
  178.             *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  179.             makename(buf,TargetDir,argv[optind],U2Suffix);
  180.             *rptr++ = salloc(buf);        /* also remove .u2 */
  181.             }
  182.          else if (smatch(fp->ext,U1Suffix) || smatch(fp->ext,U2Suffix)
  183.                || smatch(fp->ext,USuffix)) {
  184.             makename(buf,TargetDir,argv[optind],U1Suffix);
  185.             *lptr++ = salloc(buf);
  186.             }
  187.          else
  188.             quitf("bad argument %s",argv[optind]);
  189.          }
  190.       optind++;
  191.       }
  192.  
  193.    *tptr = *lptr = *rptr = NULL;    /* terminate filename lists */
  194.    if (lptr == lfiles)
  195.       usage();                /* error -- no files named */
  196.  
  197.    /*
  198.     * Round hash table sizes to next power of two, and set masks for hashing.
  199.     */
  200.    chsize = round2(chsize);  cmask = chsize - 1;
  201.    fhsize = round2(fhsize);  fmask = fhsize - 1;
  202.    ghsize = round2(ghsize);  gmask = ghsize - 1;
  203.    ihsize = round2(ihsize);  imask = ihsize - 1;
  204.    lhsize = round2(lhsize);  lmask = lhsize - 1;
  205.  
  206.    /*
  207.     * Translate .icn files to make .u1 and .u2 files.
  208.     */
  209.    if (tptr > tfiles) {
  210.       if (!silent)
  211.          report("Translating");
  212.       errors = trans(tfiles);
  213.       if (errors > 0)            /* exit if errors seen */
  214.          exit(ErrorExit);
  215.       }
  216.  
  217.    /*
  218.     * Link .u1 and .u2 files to make an executable.
  219.     */
  220.    if (nolink)                /* exit if no linking wanted */
  221.  
  222. #if MACINTOSH
  223. #if MPW
  224.       /*
  225.        *  Set type of translator output ucode (.u) files
  226.        *  to 'TEXT', so they can be easily viewed by editors.
  227.        */
  228.       {
  229.       char **p;
  230.       void setfile();
  231.       for (p = rfiles; *p; ++p)
  232.          setfile(*p,'TEXT','icon');
  233.       }
  234. #endif                    /* MPW */
  235. #endif                    /* MACINTOSH */
  236.  
  237.       exit(NormalExit);
  238.  
  239.    if (ofile == NULL)  {        /* if no -o file, synthesize a name */
  240.       ofile = salloc(makename(buf,TargetDir,lfiles[0],IcodeSuffix));
  241.    } else {                /* add extension in necessary */
  242.       fp = fparse(ofile);
  243.  
  244. #if !(MACINTOSH && MPW) /* This code provokes code generation bug in */
  245.         /* pre-release MPW 3.0 C compiler */
  246.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given, but wanted */
  247.          ofile = salloc(makename(buf,TargetDir,ofile,IcodeSuffix));
  248. #endif                    /* !(MACINTOSH && MPW) */
  249.  
  250.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  251.          ofile = salloc(makename(buf,TargetDir,ofile,IcodeSuffix));
  252.    }
  253.  
  254.    if (!silent)
  255.       report("Linking");
  256.    errors = ilink(lfiles,ofile);    /* link .u files to make icode file */
  257.  
  258.    /*
  259.     * Finish by removing intermediate files.
  260.     *  Execute the linked program if so requested and if there were no errors.
  261.     */
  262.  
  263. #if MACINTOSH
  264. #if MPW
  265.    /* Set file type to TEXT so it will be executable as a script. */
  266.    setfile(ofile,'TEXT','icon');
  267. #endif                    /* MPW */
  268. #endif                    /* MACINTOSH */
  269.  
  270.    rmfiles(rfiles);            /* remove intermediate files */
  271.    if (errors > 0) {            /* exit if linker errors seen */
  272.       unlink(ofile);
  273.       exit(ErrorExit);
  274.       }
  275.  
  276.    if (optind < argc)  {
  277.       if (!silent)
  278.          report("Executing");
  279.       execute (ofile, efile, argv+optind+1);
  280.       }
  281.  
  282.    exit(NormalExit);
  283.    }
  284.  
  285. /*
  286.  * execute - execute iconx to run the icon program
  287.  */
  288. static novalue execute(ofile,efile,args)
  289. char *ofile, *efile, **args;
  290.    {
  291.    int n;
  292.    char **argv, **p;
  293.  
  294.    for (n = 0; args[n] != NULL; n++)    /* count arguments */
  295.       ;
  296.    p = argv = (char **)alloc((unsigned int)((n + 5) * sizeof(char *)));
  297.  
  298.    *p++ = Iconx;            /* set iconx pathname */
  299.    if (efile != NULL) {            /* if -e given, copy it */
  300.       *p++ = "-e";
  301.       *p++ = efile;
  302.       }
  303.    *p++ = ofile;            /* pass icode file name */
  304.  
  305. #if AMIGA && LATTICE
  306.    *p = *args;
  307.    while (*p++) {
  308.       *p = *args;
  309.       args++;
  310.    }
  311. #else                    /* AMIGA && LATTICE */
  312.    while (*p++ = *args++)        /* copy args into argument vector */
  313.       ;
  314. #endif                    /* AMIGA && LATTICE */
  315.  
  316.    *p = NULL;
  317.  
  318. /*
  319.  * The following code is operating-system dependent [@tmain.02].  It calls
  320.  *  iconx on the way out.
  321.  */
  322.  
  323. #if PORT
  324.    /* something is needed */
  325. Deliberate Syntax Error
  326. #endif                    /* PORT */
  327.  
  328. #if AMIGA
  329. #if AZTEC_C
  330.       execvp(Iconx,argv);
  331.       return;
  332. #endif                    /* AZTEC_C */
  333. #if LATTICE
  334.       {
  335.       struct ProcID procid;
  336.       if (forkv(Iconx,argv,NULL,&procid) == 0) { 
  337.          wait(&procid);
  338.          return;
  339.          }
  340.       }
  341. #endif                    /* LATTICE */
  342. #endif                    /* AMIGA */
  343.  
  344. #if ATARI_ST || MVS || VM
  345.       /* Forkvp(Iconx,argv); */
  346.       /* return; */
  347.       fprintf(stderr,"-x not supported\n");
  348.       fflush(stderr);
  349.      /* not implemented yet */
  350. #endif                    /* ATARI_ST || MVS || VM */
  351.  
  352. #if HIGHC_386
  353.       fprintf(stderr,"-x not supported\n");
  354.       fflush(stderr);
  355.      /* not implemented yet */
  356. #endif                    /* HIGHC_386 */
  357.  
  358. #if MACINTOSH
  359. #if MPW
  360.       /*
  361.        *  Something slightly different ...
  362.        */
  363.       {
  364.       char *s;
  365.       char *mpwquote();
  366.  
  367.       fputs(Iconx,stdout);
  368.       for (p = argv + 1; *p; ++p) {
  369.          putchar(' ');
  370.      fputs(s = mpwquote(*p),stdout);
  371.      free(s);
  372.      }
  373.       putchar('\n');
  374.       return;
  375.       }
  376. #endif                    /* MPW */
  377. #if LSC
  378.       fprintf(stderr,"-x not supported\n");
  379.       fflush(stderr);
  380. #endif                    /* LSC */
  381. #endif                    /* MACINTOSH */
  382.  
  383. #if MSDOS
  384. #if LATTICE || MICROSOFT || TURBO
  385.       execvp(Iconx,argv);    /* execute with path search */
  386. #endif                    /* LATTICE || MICROSOFT || TURBO */
  387. #if MWC
  388.       fprintf(stderr,"-x not supported\n");
  389.       fflush(stderr);
  390.       /* execall(Iconx,argv); */
  391. #endif                    /* MWC */
  392. #endif                    /* MSDOS */
  393.  
  394. #if MVS || VM
  395. #if SASC
  396.       exit(sysexec(Iconx, argv));
  397. #endif                    /* SASC */
  398. #endif                                  /* MVS || VM */
  399.  
  400. #if OS2
  401.       execvp(Iconx,argv);    /* execute with path search */
  402. #endif                    /* OS2 */
  403.  
  404. #if UNIX
  405.       /*
  406.        * If an ICONX environment variable is defined, use that.
  407.        *  If not, first try the predefined path, then search $PATH via execvp. 
  408.        */
  409.       if ((argv[0] = getenv("ICONX")) != NULL && argv[0][0] != '\0') {
  410.          execv(argv[0], argv);    /* exec file specified by $ICONX */
  411.          quitf("cannot execute $ICONX (%s)", argv[0]);
  412.          }
  413.  
  414. #ifdef HardWiredPaths
  415. #ifdef CRAY
  416.       argv[0] = "iconx";
  417.       execv(Iconx, argv);
  418. #else                    /* CRAY */
  419.       argv[0] = Iconx;        /* try predefined file */
  420.       execv(argv[0], argv);
  421. #endif                    /* CRAY */
  422. #endif                    /* HardWiredPaths */
  423.  
  424.       argv[0] = "iconx";
  425.       execvp(argv[0], argv);    /* if no Iconx, search path for "iconx" */
  426.  
  427. #ifdef HardWiredPaths
  428.       quitf("cannot run %s", Iconx);
  429. #else                    /* HardWiredPaths */
  430.       quitf("cannot find iconx", "");
  431. #endif                    /* HardWiredPaths */
  432. #endif                    /* UNIX */
  433.  
  434. #if VMS
  435.       execv(Iconx,argv);
  436. #endif                    /* VMS */
  437.  
  438. /*
  439.  * End of operating-system specific code.
  440.  */
  441.  
  442.    quitf("could not run %s",Iconx);
  443.    }
  444.  
  445. static novalue report(s)
  446. char *s;
  447.    {
  448.  
  449. /*
  450.  * The following code is operating-system dependent [@tmain.03].  Report
  451.  *  phase.
  452.  */
  453.  
  454. #if PORT
  455.    fprintf(stderr,"%s:\n",s);
  456. Deliberate Syntax Error
  457. #endif                    /* PORT */
  458.  
  459. #if AMIGA || ATARI_ST || HIGHC_386 || MSDOS || MVS || OS2 || UNIX || VM || VMS
  460.    fprintf(stderr,"%s:\n",s);
  461. #endif                    /* AMIGA || ATARI_ST || HIGHC_386 ... */
  462.  
  463. #if MACINTOSH
  464. #if MPW
  465.    printf("Echo '%s:' > Dev:StdErr\n",s);
  466. #endif                    /* MPW */
  467. #if LSC
  468.    fprintf(stderr,"%s:\n",s);
  469. #endif                    /* LSC */
  470. #endif                    /* MACINTOSH */
  471.  
  472. /*
  473.  * End of operating-system specific code.
  474.  */
  475.  
  476.    }
  477.  
  478. /*
  479.  * rmfiles - remove a list of files
  480.  */
  481.  
  482. static novalue rmfiles(p)
  483. char **p;
  484.    {
  485.    for (; *p; p++) {
  486. /*
  487.  * The following code is operating-system dependent [@tmain.04].
  488.  *  remove files.
  489.  */
  490.  
  491. #if PORT
  492.       unlink(*p);
  493. Deliberate Syntax Error
  494. #endif                    /* PORT */
  495.  
  496. #if AMIGA || ATARI_ST || HIGHC_386 || MSDOS || MVS || OS2 || UNIX || VM || VMS
  497.       unlink(*p);
  498. #endif                    /* AMIGA || ATARI_ST ... */
  499.  
  500. #if MACINTOSH
  501. #if MPW
  502.       /*
  503.        * MPW generates commands rather than doing the actions
  504.        *  at this time.
  505.        */
  506.       fprintf(stdout,"Delete %s\n", *p);
  507. #endif                    /* MPW */
  508. #if LSC
  509.       unlink(*p);
  510. #endif                    /* LSC */
  511. #endif                    /* MACINTOSH */
  512.  
  513. /*
  514.  * End of operating-system specific code.
  515.  */
  516.       }
  517.    }
  518.  
  519. /*
  520.  * Print an error message if called incorrectly.  The message depends
  521.  *  on the legal options for this system.
  522.  */
  523. static novalue usage()
  524.    {
  525.    fprintf(stderr,"usage: %s %s file ... [-x args]\n", progname, Usage);
  526.    exit(ErrorExit);
  527.    }
  528.